package core.controls;
import ibm.widgets.WButton;
import ibm.widgets.WComboBox;
import ibm.widgets.WListBox;
import ibm.widgets.WRadioButton;

import com.rational.test.ft.ObjectNotFoundException;
import com.rational.test.ft.object.interfaces.TestObject;
import com.rational.test.util.regex.Regex;

import core.exceptions.ResultFailureException;
import core.testcases.TestObj;
/**
 * Description   : Functional Test Script
 * @author angel.tsvetkov
 */
public class SelectBox extends Control<WComboBox>
{
	public SelectBox(String propertyValue, String propertyName,
			String objClass, TestObject parent, String descriptiveName) {
		super(propertyValue, propertyName, objClass, parent, descriptiveName);
		// TODO Auto-generated constructor stub
	}
	
	public SelectBox(TestObject object, String descriptiveName) {
		super(object, descriptiveName);
		this.obj = null;
	}

	/**
	 * Description : Select option from list box.
	 * 
	 * @param propValue - property value which is used for select box determination
	 * 
	 * @param propName - property name which is used for select box determination
	 * 
	 * @param targetOption - option which will be chosen
	 * 
	 * @param parent - area in which the image belongs.
	 */
	public boolean selectOption(Object option)
	{
        boolean result = false;
        String taskReport = "";

        try
        {
            taskReport = " \n Select " + option.toString() + " option from " + this.getDescriptiveName();
            this.select(option);
            result = true;
        }
        catch (ResultFailureException e)
        {
        	setErrorComment("Problem appear in selecting option of select box with prop name: " + this.PropName() + " and prop value: " + this.PropValue(),e);
        	result = false;
        }
        setTaskResult("Task: Select " + option.toString() + " from " + this.getDescriptiveName(), result, taskReport);

		return result;
	}
		
	public boolean select(Object targetOption)
			throws ResultFailureException {
		// Initialize variables
		boolean result = false;
		WComboBox listSelect = null;

		// Perform choose item from list
		try {
			// Allocate List Box
			listSelect = this.get();

			if (targetOption instanceof String) {
				// if target option is string
				if(!listSelect.select((String) targetOption))
				{
					throw new ResultFailureException(
							"Unexpected assertion on choosing item from " + this.getDescriptiveName());
				}
			} else {
				// if target option is number
				if(listSelect.select((Integer) targetOption))
				{
					throw new ResultFailureException(
							"Unexpected assertion on choosing item from " + this.getDescriptiveName());
				}
			}	
			result = true;
		} catch (Exception e) {
			result = false;
			throw new ResultFailureException(
					"Unexpected assertion on choosing item from " + this.getDescriptiveName());
		}
		finally
		{
			// Unregister object
			listSelect.unregister();
		}

		return result;
	}
	
	public static boolean select(WListBox filter, Object targetOption) throws ResultFailureException {
		// Initialize variables
		boolean result = false;
		//WListBox listSelect = null;

		// Perform choose item from list
		try {
			// Allocate List Box
			//listSelect = this.get();

			if (targetOption instanceof String) {
				// if target option is string
				filter.select((String) targetOption);
			} else {
				// if target option is number
				filter.select((Integer) targetOption);
			}

			result = true;
		} catch (Exception e) {
			throw new ResultFailureException(
					"Unexpected assertion on choosing item from " + filter.getDescriptiveName());
		}
		//finally
		//{
			// Unregister object
		//	listSelect.unregister();
		//}

		return result;
	}
	
	public String[] getContent()
	{
		return this.get().getContents();
	}
	
	/**
	 * Description : Verify all exists options in the select box.
	 * 
	 * @param listSelect - select box object representation
	 * 
	 * @param options - expected options
	 */
	public static boolean verifyOptions(WListBox listSelect, String[] options) throws ResultFailureException
	{
		boolean result = false;
		// Verify that expected options count is the same as the real list
		// box options count
		if (options.length == listSelect.getContents().length) {
			
			//if there is no options
			if (options.length == 0) {
				return true;
			}

			//Iterate through all options
			for (String option : options) {
				//Iterate through all available options
				for (String availableOptions : listSelect.getContents()) {
					//If the expected option and the real option are equal
					if (availableOptions.equals(option)) {
						result = true;
						break;
					} else {
						//If the expected option and the real option aren't equal
						result = false;
					}
				}
				//If expected option does not exist
				if (result == false) {
					throw new ResultFailureException(
							"Option does not exist!");
				}
			}
			
			//Unregister object
			listSelect.unregister();
		} else {
			throw new ResultFailureException(
					"There is a difference between available options count and verifyed options count!");
		}

		return result;
	}
	
	/**
	 * Description :  Verify all exists options in the select box.
	 * 
	 * @param propValue - property value which is used for select box determination
	 * 
	 * @param propName - property name which is used for select box determination
	 * 
	 * @param options - expected options
	 * 
	 * @param parent - area in which the select box belongs.
	 */
	public boolean verifyOptions(String... options)
			throws ResultFailureException {
		// Initialize variables
		WListBox listSelect = null;

		// Perform choose item from list
		try {
			// Allocate List Box
			listSelect = this.get();
		} catch (Exception e) {
			throw new ResultFailureException(
					"Unexpected assertion on choosing item from " + this.getDescriptiveName());
		}
		return verifyOptions(listSelect, options);	
	}
	
	/**
	 * Description :  Get select box current option
	 * 
	 * @param propValue - property value which is used for select box determination
	 * 
	 * @param propName - property name which is used for select box determination
	 * 
	 * @param parent - area in which the select box belongs.
	 */
	public String getSelected()
			throws ResultFailureException {
		// Initialize variables
		String result;
		WListBox listSelect = null;

		// Perform choose item from list
		try {
			//Allocate List Box
			listSelect = this.get();
			
			//Get current option
			result = listSelect.getSelText();
			
		} catch (Exception e) {
			throw new ResultFailureException(
					"Unexpected assertion on selecting" + this.getDescriptiveName());
		}
		finally
		{
			// Unregister object
			listSelect.unregister();
		}

		return result;
	}
	
    public boolean verifyAvailableOptions(String... options)
	{
        boolean result = false;
        String taskReport = "";

        try
        {
            taskReport += " \n Verify that " + this.getDescriptiveName() + " available options are: \n";
            for(String option:options)
            {
            	taskReport += "  " + option + "\n";
            }

            this.verifyOptions(options);
            result = true;
            
        }
        catch (ResultFailureException e)
        {
        	setErrorComment("Problem appear in verification of available options in select box with prop name: " + this.PropName() + " and prop value: " + this.PropValue(),e);
            
        }
        setTaskResult("Task: Verify available " + this.getDescriptiveName() + " options.", result, taskReport);

		return result;
	}
    
    public boolean verifyCurrentOption(String option)
	{
        boolean result = false;
        String taskReport = "";

        try
        {
            taskReport += " \n Verify that " + this.getDescriptiveName() + " current option is " + option;
            result = this.getSelected().equals(option);
            result = true;
        }
        catch (ResultFailureException e)
        {
        	setErrorComment("Problem appear in verification of the current option of select box with prop name: " + this.PropName() + " and prop value: " + this.PropValue(),e);
        }
        setTaskResult("Task: Verify " + this.getDescriptiveName() + " current option.", result, taskReport);

		return result;
	}
    
    
    public boolean optionIsNotAvailable(String option)
	{
        boolean result = false;
        boolean valuesComparision = false;
        String taskReport = "";

		TestObject obj = this.get();
		WComboBox selectBoxValues = new WComboBox(obj);
			
    	for (int i=0; i<selectBoxValues.getItemCount(); i++)
    	{
        	String selectBoxValue = new String();
        	selectBoxValue = selectBoxValues.getItemText(i);
        	valuesComparision = selectBoxValue.equals(option);
        	
        	if(valuesComparision)
        	{
	    		taskReport += " \n Recently Deleted option " + option + " is still in the " + this.getDescriptiveName() + " list."  ;
	    		result = false;
        	break;
        	}
        	else
        	{
                result = true;
        	}
    	}
    	taskReport += " \n Verify that " + option + " option is not in the " +  this.getDescriptiveName() + " list." ;
        setTaskResult("Task: Verify " + this.getDescriptiveName() + " deleted option.", result, taskReport);
        return result;
	} 
  
    
	@Override
	public WComboBox get() {
		if(isCreatedFromTestObject())
		{
			this.obj = new WComboBox(testObject);
		}
		else
		{
			if(this.isCognosControl())
			{
				TestObject parent = this.getParent();
				this.obj = new WComboBox(parent.getChildren()[0]);
			}
			else
			{
				Regex toSearch = new Regex(this.PropValue(), Regex.MATCH_MULTILINE);
				this.obj = new WComboBox(toSearch,this.PropName(),this.getObjClass(),this.getParent());
			}
		}
		return this.obj;
	}

	@Override
	public boolean isEnabled() {
		return this.get().isEnabled();
	}

	@Override
	public boolean isExist() {
		boolean result = false;
		try
		{
			result = this.get().ensureObjectIsVisible();	
		}catch(ObjectNotFoundException ex)
		{
			result = false;
		}
		return result;
	}
	
}

